<template>
  <basePage>
    <el-card>
      <el-row class="diy-row" :gutter="12">
        <el-col :span="2">
          <el-button type="primary" @click="showCreateDialog">添加用例</el-button>
        </el-col>
        <el-col :span="6">
          <el-input placeholder="请输入内容" v-model="query" clearable @clear="removeSearch">
            <el-button slot="append" icon="el-icon-search" @click="searchCase"></el-button>
          </el-input>
        </el-col>
      </el-row>
      <el-table :data="caseList" border>
        <el-table-column label="用例名" prop="case_name"></el-table-column>
        <el-table-column
          label="请求方法"
          prop="request_type"
          show-overflow-tooltip
          width="78"
        ></el-table-column>
        <el-table-column
          label="请求头"
          prop="headers"
          width="100"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column label="参数类型" prop="param_type" show-overflow-tooltip></el-table-column>
        <el-table-column label="参数" prop="param" show-overflow-tooltip></el-table-column>
        <el-table-column label="任务类型" prop="job_type"></el-table-column>
        <el-table-column label="任务时间" prop="job_cron"></el-table-column>
        <el-table-column label="预期类型" prop="expect_type" width="80"></el-table-column>
        <el-table-column
          label="预期结果"
          prop="expect"
          width="100"
          show-overflow-tooltip
        ></el-table-column>
        <el-table-column label="状态" prop="status" width="103px">
          <template scope="scope">
            <el-tag v-if="scope.row.status === 1" effect="dark" type="success">RUNNING</el-tag>
            <el-tag v-else effect="dark" type="info">STOP</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="243px">
          <template scope="scope">
            <el-button
              size="mini"
              type="primary"
              icon="el-icon-edit"
              @click="showEditDialog(scope.row.id)"
            ></el-button>
            <el-button
              size="mini"
              type="danger"
              icon="el-icon-delete"
              @click="removeCase(scope.row.id)"
            ></el-button>
            <el-dropdown
              :split-button="true"
              type="warning"
              size="mini"
              @command="handleDropdownCommand"
            >
              更多操作
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item :command="beforeHandleDropdownCommand(scope.row.id, 'startJob')"
                  >启动任务</el-dropdown-item
                >
                <el-dropdown-item :command="beforeHandleDropdownCommand(scope.row.id, 'pauseJob')"
                  >停止任务</el-dropdown-item
                >
                <el-dropdown-item :command="beforeHandleDropdownCommand(scope.row.id, 'resumeJob')"
                  >恢复任务</el-dropdown-item
                >
                <el-dropdown-item
                  divided
                  :command="beforeHandleDropdownCommand(scope.row.id, 'runNow')"
                  >执行一次</el-dropdown-item
                >
                <!-- <el-dropdown-item>详情</el-dropdown-item> -->
                <!-- <el-dropdown-item>下次执行时间</el-dropdown-item> -->
              </el-dropdown-menu>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <el-dialog
      :title="dialogTitle"
      :visible.sync="caseDialogVisible"
      width="30%"
      @close="closeDialog"
    >
      <el-form :model="caseInfo" :rules="caseInfoRules" ref="caseInfoRef" label-width="100px">
        <el-form-item label="用例名称" prop="case_name">
          <el-input v-model="caseInfo.case_name" placeholder="请输入用例名称"></el-input>
        </el-form-item>
        <el-form-item label="请求方法" prop="request_type_id">
          <el-select v-model="caseInfo.request_type_id" placeholder="请选择请求方法" clearable>
            <el-option
              v-for="item in request_types"
              :key="item.id"
              :label="item.dict_value"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="请求头" prop="headers">
          <el-input v-model="caseInfo.headers" placeholder="请输入请求头"></el-input>
        </el-form-item>
        <el-form-item label="参数类型" prop="param_type_id">
          <el-select v-model="caseInfo.param_type_id" placeholder="请选择参数类型" clearable>
            <el-option
              v-for="item in param_types"
              :key="item.id"
              :label="item.dict_value"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="参数" prop="param">
          <el-input v-model="caseInfo.param" placeholder="请输入请求参数"></el-input>
        </el-form-item>
        <el-form-item label="任务类型" prop="job_type_id">
          <el-select v-model="caseInfo.job_type_id" placeholder="请选择任务类型" clearable>
            <el-option
              v-for="item in job_types"
              :key="item.id"
              :label="item.dict_value"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="任务时间" prop="job_cron">
          <el-input
            v-if="caseInfo.job_type_id === 6"
            v-model="caseInfo.job_cron"
            placeholder="请输入任务时间 [cron 表达式]"
          ></el-input>
          <el-date-picker v-else-if="caseInfo.job_type_id === 7" v-model="caseInfo.job_cron" value-format="yyyy-MM-dd HH:mm:ss" type="datetime" placeholder="选择日期时间">
          </el-date-picker>
          <el-input
            v-else-if="caseInfo.job_type_id === 8"
            v-model="caseInfo.job_cron"
            placeholder="请输入间隔执行时间 [单位 s]"
          ></el-input>
        </el-form-item>
        <el-form-item label="预期类型" prop="expect_type_id">
          <el-select v-model="caseInfo.expect_type_id" placeholder="请选择预期类型" clearable>
            <el-option
              v-for="item in expect_types"
              :key="item.id"
              :label="item.dict_value"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="预期结果" prop="expect">
          <el-input v-model="caseInfo.expect" placeholder="请输入预约结果"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="caseDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="createOrEditCase">确 定</el-button>
      </span>
    </el-dialog>
  </basePage>
</template>

<script>
export default {
  data() {
    return {
      urlId: null,
      caseList: [],
      query: '',
      dialogTitle: '',
      createCase: null,
      caseDialogVisible: false,
      caseInfo: {},
      caseInfoRules: {
        case_name: [
          {
            required: true,
            message: '请输入用例名称',
            triger: 'blur'
          }
        ],
        request_type_id: [
          {
            required: true,
            message: '请选择请求方法',
            trigger: 'change',
            type: 'number'
          }
        ],
        headers: [
          {
            required: true,
            message: '请输入请求头',
            trigger: 'blur'
          }
        ],
        param_type_id: [
          {
            required: true,
            message: '请选择参数类型',
            trigger: 'change',
            type: 'number'
          }
        ],
        param: [
          {
            required: true,
            message: '请输入请求参数',
            trigger: 'blur'
          }
        ],
        job_type_id: [
          {
            required: true,
            message: '请选择任务类型',
            trigger: 'change',
            type: 'number'
          }
        ],
        job_cron: [
          {
            required: true,
            message: '请输入任务时间 [cron 表达式]',
            trigger: 'blur'
          }
        ],
        expect_type_id: [
          {
            required: true,
            message: '请选择预期类型',
            trigger: 'change',
            type: 'number'
          }
        ],
        expect: [
          {
            required: true,
            message: '请输入预约结果',
            trigger: 'blur'
          }
        ]
      },
      request_types: [],
      param_types: [],
      job_types: [],
      expect_types: []
    }
  },
  created() {
    this.getUrlParams()
    this.getCaseList()
  },
  methods: {
    // 获取url参数
    getUrlParams() {
      this.urlId = this.$route.query.id
      this.caseInfo.api_id = this.$route.query.id
    },
    // 获取用例列表
    getCaseList() {
      this.$http
        .get(`/core/api/case/list?id=${this.urlId}`)
        .then(res => {
          const resData = res.data
          if (resData.code === 200) {
            this.caseList = resData.data.list
          } else {
            return this.$message.error(resData.msg)
          }
        })
        .catch(err => {
          return this.$message.error(err)
        })
    },
    // 显示添加用例dialog
    showCreateDialog() {
      this.getSystemDictList()
      this.dialogTitle = '添加用例'
      this.createCase = true
      this.caseDialogVisible = true
    },
    // 显示编辑用例dialog
    showEditDialog(id) {
      this.dialogTitle = '编辑用例'
      this.createCase = false
      // 获取用例详情信息
      this.$http
        .get(`/core/api/case/getById?id=${id}`)
        .then(res => {
          const resData = res.data
          if (resData.code === 200) {
            this.caseInfo = resData.data[0]
          } else {
            return this.$message.error(resData.msg)
          }
        })
        .catch(err => {
          return this.$message.error(err)
        })
      this.getSystemDictList()
      this.caseDialogVisible = true
    },
    // 新增/编辑用例
    createOrEditCase() {
      this.$refs.caseInfoRef.validate(valid => {
        if (valid) {
          if (this.createCase) {
            // 新增用例
            this.$http
              .post('/core/api/case/create', this.caseInfo)
              .then(res => {
                const resData = res.data
                if (resData.code === 200) {
                  this.caseDialogVisible = false
                  this.getCaseList()
                  this.$message.success(resData.msg)
                } else {
                  return this.$message.error(resData.msg)
                }
              })
              .catch(err => {
                return this.$message.error(err)
              })
          } else {
            // 编辑用例
            this.$http
              .post('/core/api/case/update', this.caseInfo)
              .then(res => {
                const resData = res.data
                if (resData.code === 200) {
                  this.caseDialogVisible = false
                  this.getCaseList()
                  this.$message.success(resData.msg)
                } else {
                  return this.$message.error(resData.msg)
                }
              })
              .catch(err => {
                return this.$message.error(err)
              })
          }
        }
      })
    },
    // 获取系统字典
    getSystemDictList() {
      this.$http.get('/core/dict/list').then(res => {
        const resData = res.data
        // const that = this
        if (resData.code === 200) {
          const data = resData.data.list
          data.forEach(element => {
            // 请求方法
            if (element.dict_label === 'request_type') {
              this.request_types.push(element)
            } else if (element.dict_label == 'param_type') {
              // 参数类型
              this.param_types.push(element)
            } else if (element.dict_label == 'trigger') {
              // 任务类型
              this.job_types.push(element)
            } else if (element.dict_label == 'response') {
              // 预期类型
              this.expect_types.push(element)
            }
          })
        }
      })
    },
    // 关闭dialog后操作
    closeDialog() {
      this.request_types = []
      this.param_types = []
      this.job_types = []
      this.expect_types = []
      this.$refs.caseInfoRef.resetFields()
    },
    // 删除用例
    removeCase(id) {
      this.$confirm('此操作将永久删除该用例, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.$http
            .get(`/core/api/case/delete?id=${id}`)
            .then(res => {
              const resData = res.data
              if (resData.code === 200) {
                this.getCaseList()
                this.$message.success(resData.msg)
              } else {
                return this.$message.error(resData.msg)
              }
            })
            .catch(err => {
              return this.$message.error(err)
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
    },
    // 查询用例
    searchCase() {
      this.$http
        .get(`/core/api/case/search?query=${this.query}&id=${this.urlId}`)
        .then(res => {
          const resData = res.data
          if (resData.code === 200) {
            this.caseList = resData.data.list
          } else {
            return this.$message.error(resData.msg)
          }
        })
        .catch(err => {
          return this.$message.error(err)
        })
    },
    // 清除搜索
    removeSearch() {
      this.getCaseList()
    },
    // 修改用例状态
    changeStatus(info) {
      this.$http
        .post('/core/api/case/changeStatus', { id: info.id })
        .then(res => {
          const resData = res.data
          if (resData.code === 200) {
            this.$message.success(resData.msg)
          } else {
            info.status = !info.status
            return this.$message.error(resData.msg)
          }
        })
        .catch(err => {
          info.status = !info.status
          return this.$message.error(err)
        })
    },
    // 处理下拉菜单command
    beforeHandleDropdownCommand(id, command) {
      return {
        id: id,
        command: command
      }
    },
    // 下拉操作
    handleDropdownCommand(command) {
      console.log(command)

      switch (command.command) {
        // 开启作业
        case 'startJob':
          this.$confirm('此操作将启用该任务, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
            .then(() => {
              this.$http
                .post('/job/startJob', { caseId: command.id })
                .then(res => {
                  const resData = res.data
                  if (resData.code === 200) {
                    this.$message.success(resData.msg)
                  } else {
                    return this.$message.error(resData.msg)
                  }
                })
                .catch(err => {
                  return this.$message.error(err)
                })
            })
            .catch(() => {
              this.$message({
                type: 'info',
                message: '已取消开启任务'
              })
            })
          break
        // 停止作业
        case 'pauseJob':
          this.$confirm('此操作将停止该任务, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
            .then(() => {
              this.$http
                .get(`/job/pauseOrResumeJob?caseId=${command.id}&action=pause`)
                .then(res => {
                  const resData = res.data
                  if (resData.code === 200) {
                    this.$message.success(resData.msg)
                  } else {
                    return this.$message.error(resData.msg)
                  }
                })
                .catch(err => {
                  return this.$message.error(err)
                })
            })
            .catch(() => {
              this.$message({
                type: 'info',
                message: '已取消停止任务'
              })
            })
          break
        // 恢复作业
        case 'resumeJob':
          this.$confirm('此操作将恢复该任务, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
            .then(() => {
              this.$http
                .get(`/job/pauseOrResumeJob?caseId=${command.id}&action=resume`)
                .then(res => {
                  const resData = res.data
                  if (resData.code === 200) {
                    this.$message.success(resData.msg)
                  } else {
                    return this.$message.error(resData.msg)
                  }
                })
                .catch(err => {
                  return this.$message.error(err)
                })
            })
            .catch(() => {
              this.$message({
                type: 'info',
                message: '已取消恢复任务'
              })
            })
          break
        // 运行一次
        case 'runNow':
          this.$http
            .get(`/job/runNow?caseId=${command.id}`)
            .then(res => {
              const resData = res.data
              if (resData.code === 200) {
                this.$alert(resData.data, '执行结果', {
                  confirmButtonText: '确定',
                  lockScroll: false
                })
                this.$message.success(resData.msg)
              } else {
                return this.$message.error(resData.msg)
              }
            })
            .catch(err => {
              return this.$message.error(err)
            })
          break
      }
    }
  }
}
</script>

<style lang="less" scoped>
@import './Case.less';
</style>
